/**
 * @param {number[]} nums
 * @return {number}
 */
// 对于数组的动态规划、子序列、连续子序列最常见的状态定义是
// 以下标i结尾的某某最优值，这个i需要被选取
var maxProduct = (nums) => {
  const dp = new Array(nums.length).fill().map((value, index) => {
    return [[nums[index]], nums[index]]
  })
  for(let i = 1; i < nums.length; i++) {
    if(nums[i] >= 0) { // 要区分大于0
      dp[i][0] = Math.max(nums[i], dp[i - 1][0] * nums[i])
      dp[i][1] = Math.min(nums[i], dp[i - 1][1] * nums[i])
    } else {
      dp[i][0] = Math.max(nums[i], dp[i - 1][1] * nums[i])
      dp[i][1] = Math.min(nums[i], dp[i - 1][0] * nums[i])
    }
  }
  let ans = nums[0]
  for(let i = 0; i < dp.length; i++) {
    ans = Math.max(ans, dp[i][0])
  }
  return ans
}

// 先用动态规划的思路
// 以便理解第二种写法
// 这里也是动态规划，只不过用了滚动数组的方法
var maxProduct = function(nums) {
  let max = nums[0]
  let cmax = 1, cmin = 1
  for(let i = 0; i < nums.length; i++) {
    if(nums[i] < 0) {
      let temp = cmax
      cmax = cmin
      cmin = temp
    }
    cmax = Math.max(cmax, cmax * nums[i])
    cmin = Math.max(cmin, cmin * nums[i])
    max = Math.max(cmax, max)
  }
  return max
};